/*
This is part of Screenbar, which is based in part on the Litestep
shell source code.

Copyright (C) 2008-2009 Jim Babcock
Copyright (C) 1997-2009 The LiteStep Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "stdafx.h"

BranchElement::BranchElement(string prefix)
	:LayoutElement(prefix)
{
	char *branchNames = _strdup(getConfigLine("Branches", "", prefix.c_str()).c_str());
	vector<string> tokenizedBranchNames;
	const char *separators = " \t\n";
	char *pos = strtok(branchNames, separators);
	while(pos) {
		tokenizedBranchNames.push_back(pos);
		pos = strtok(NULL, separators);
	}
	free(branchNames);
	
	for(unsigned ii=0; ii<tokenizedBranchNames.size(); ii++) {
		branches.push_back(parseBranch(tokenizedBranchNames[ii]));
	}
	
	this->childrenCanChange = true;
}

BranchElement::Branch BranchElement::parseBranch(const string &prefix)
{
	Branch ret;
	ret.element = layoutPool->getElement(prefix);
	string conditionVar = prefix+"Condition";
	string conditionStr = getConfigLine(conditionVar.c_str(), "true", "");
	const char *conditionCstr = conditionStr.c_str();
	ret.condition = parseExpression(conditionCstr);
	return ret;
}

BranchElement::~BranchElement()
{
	for(unsigned ii=0; ii<branches.size(); ii++)
		delete branches[ii].condition;
}

ElementSize BranchElement::getLength(const LayoutCacheNode *node)
{
	if(node->children.size() > 0)
		return node->children[0]->size;
	else {
		ElementSize ret;
		ret.minimum = ret.preferred = 0;
		return ret;
	}
}

void BranchElement::getChildren(LayoutCacheNode *node, vector<LayoutLocation> &outChildren)
{
	LayoutElement *branch = getBranch(&node->context);
	if(branch) {
		LayoutLocation child;
		child.element = branch;
		child.context = node->context;
		outChildren.push_back(child);
	}
}

void draw(HDC drawContext, const LayoutCacheNode *node)
{
	for(unsigned ii=0; ii<node->children.size(); ii++)
	{
		LayoutCacheNode *child = node->children[ii];
		child->element->draw(drawContext, child);
	}
}


LayoutElement *BranchElement::getBranch(const ElementContext *context)
{
	for(unsigned ii=0; ii<branches.size(); ii++)
	{
		if(!branches[ii].condition)
			return branches[ii].element;
		if(branches[ii].condition->evaluate(context))
			return branches[ii].element;
	}
	return NULL;
}

